/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package unilearn.bo;

import java.util.ArrayList;
import java.util.List;
import unilearn.dao.AssignmentDAO;
import unilearn.dao.MarkDAO;
import unilearn.dao.MarkSheetDAO;
import unilearn.vo.Assignment;
import unilearn.vo.Mark;
import unilearn.vo.MarkSheet;
import unilearn.vo.MarkSheet;
import unilearn.vo.Submission;

/**
 *
 * @author Ming
 */
public class MarkManagement {
    
    private MarkSheetDAO markSheetDAO;
    private MarkDAO markDAO;
    private AssignmentDAO assignmentDAO;
    
    public MarkManagement() {
        markSheetDAO = null;
        markDAO = null;
        assignmentDAO = null;
    }
    
    public MarkManagement(MarkSheetDAO markSheetDAO, MarkDAO markDAO, AssignmentDAO assignmentDAO) {
        this();
        this.markSheetDAO = markSheetDAO;
        this.markDAO = markDAO;
        this.assignmentDAO = assignmentDAO;
    }
    
    public void setMarkDAO(MarkDAO markDAO) {
        this.markDAO = markDAO;
    }
    
    public void setMarkSheetDAO(MarkSheetDAO markSheetDAO) {
        this.markSheetDAO = markSheetDAO;
    }
    
    public void setAssignmentDAO(AssignmentDAO assignmentDAO) {
        this.assignmentDAO = assignmentDAO;
    }
    
    public List<MarkSheet> getMarkSheet(Assignment assignment) throws Exception {
        MarkSheet ms = new MarkSheet();
        ms.setAssignmentId(assignment.getId());
        ms.setSubjectCode(assignment.getSubjectCode());
        
        return markSheetDAO.find(ms);
    }
    
    public List<MarkSheet> createMarkSheet(Assignment assignment, List<MarkSheet> markSheets) throws Exception {
        List<MarkSheet> mss = new ArrayList();
        for (MarkSheet markSheet : markSheets) {
            MarkSheet ms = markSheetDAO.insert(markSheet);
            if (ms != null) {
                mss.add(ms);
            }
        }
        
        return mss;
    }
    
    public List<MarkSheet> updateMarkSheet(List<MarkSheet> markSheets) throws Exception {
        List<MarkSheet> mss = new ArrayList();
        for (MarkSheet markSheet : markSheets) {
            MarkSheet ms = markSheetDAO.update(markSheet);
            if (ms != null) {
                mss.add(ms);
            }
        }
        
        return mss;
    }
    
    public void removeMarkSheet(List<MarkSheet> markSheets) throws Exception {
        for (MarkSheet markSheet : markSheets) {
            markSheetDAO.delete(markSheet);
        }
    }
    
    public List<Mark> generateMarkList(Submission submission) throws Exception {
        MarkSheet markSheet = new MarkSheet();
        markSheet.setAssignmentId(submission.getAssignmentId());
        List<MarkSheet> mss = markSheetDAO.find(markSheet);
        if ((mss == null) || (mss.isEmpty())) {
            return null;
        }
        
        List<Mark> marks = new ArrayList();
        for (MarkSheet ms : mss) {
            Mark m = new Mark();
            m.setSubjectCode(ms.getSubjectCode());
            m.setAssignmentId(ms.getAssignmentId());
            m.setSubmissionId(submission.getId());
            m.setMarkSheetId(ms.getId());
            marks.add(m);
        }
        
        return marks;
    }
    
    public List<Mark> markSubmission(Submission submission, List<Mark> marks) throws Exception {
        Assignment assign = assignmentDAO.get(submission.getAssignmentId());
        if (assign == null) {
            throw new Exception("Could not find assignment(ID: " + submission.getAssignmentId() + ").");
        }
        
        List<MarkSheet> markSheets = this.getMarkSheet(assign);
        
        for (Mark m : marks) {
            if (!m.getSubjectCode().equals(submission.getSubjectCode())) {
                throw new Exception("Subject Code is not match.");
            }
            if (m.getAssignmentId() != submission.getAssignmentId()) {
                throw new Exception("Assignment ID is not match.");
            }
            if (m.getSubmissionId() != submission.getId()) {
                throw new Exception("Submission ID is not match.");
            }
            
            for (MarkSheet ms : markSheets) {
                if (m.getMarkSheetId() == ms.getId()) {
                    if(m.getMark() > ms.getMaxMark()){
                        throw new Exception("Mark can not more than max mark.");
                    }
                }
            }
        }
        
        MarkSheet sheet = new MarkSheet();
        sheet.setSubjectCode(submission.getSubjectCode());
        sheet.setAssignmentId(submission.getAssignmentId());
        List<MarkSheet> sheets = markSheetDAO.find(sheet);
        
        List< Mark> ms = new ArrayList();
        for (Mark m : marks) {
            ms.add(markDAO.insert(m));
        }
        
        return ms;
    }
    
    private List<Mark> checkMark(Submission submission, List<Mark> marks, List<MarkSheet> sheets) throws Exception {
        Mark searchMark = new Mark();
        searchMark.setSubjectCode(submission.getSubjectCode());
        searchMark.setAssignmentId(submission.getAssignmentId());
        List<Mark> ms = markDAO.find(searchMark);
        
        if ((ms == null) || (ms.isEmpty())) {
            ms = new ArrayList();
            for (Mark m : marks) {
                ms.add(markDAO.insert(m));
            }
        } else {
            List<Mark> resMark = new ArrayList();
            for (Mark m : ms) {
                boolean isUpdate = false;
                for (Mark mark : marks) {
                    if (m.getId() == mark.getId()) {
                        m = mark;
                        isUpdate = true;
                        break;
                    }
                }
                if (isUpdate) {
                    resMark.add(markDAO.update(m));
                }
            }
            ms.clear();
            ms.addAll(resMark);
        }
        
        return ms;
    }
    
    public void removeMark(List<Mark> marks) throws Exception {
        for (Mark m : marks) {
            markDAO.delete(m);
        }
    }
}
